# Identifying & Defeating Packing
***

# Tools
## PEiD:

* No longer maintained

* Signature DB is still used by other tools such as PE Studio

* Signatures can be updated - userdb.txt, you can add to it yourself or find someone who is maintaining an updated version

* Contains other plugins that may execute your sample program


## Detect-it-easy (Die):

* Available on github

* Open signature architecture - you can add your own signatures

* Signature format is more robust which leads to higher accuracy

* Contains: hex editor, address calculations & more

* Measures entropy & provides it w/a graph view


# Module 2

Packed - Programs which are packed are compressed or obfuscated within another program. These programs can not be analyzed until they're unpacked. Packing is a subset of obfuscation & can affect both static & dynamic analysis.

* Packing techniques vary & will require different approaches to defeat

* If you don't unpack, you're analyzing the unpacking code & not the intended payload


**Packing Simplified:**

When you have an executable (.exe) or dynamic link library (.dll), you're able to look at the strings, imports, sections, & sources & even see that the file has low entropy.

But when the malware author uses a packer, it becomes a packed executable & this masks the original payload (the exe or dll). All of the strings, imports, sections, & resources are hidden & cannot be inspected until the original payload can't be analyzed until it's unpacked.


**Packing For a Good Cause:**
Packing can have legitimate uses such as:

* protecting intellectual property in software

* can decrease the size of the original software

This can make differentiating between good & malicious software difficult. Just because software is packed, doesn't mean it's malicious.


**Common Packing Scenarios:**

Using commercial or open-source packer:

* identified through packing signatures

* easy to find unpacking software

* payload is compressed/encrypted into new exectuable


Crimeware or lesser known packer is used:

* might be more difficult to detect, not readily available for research

* signatures to detect isn't available


Modular unpackers:

* rely on numerous stages of shellcode to help w/unpacking process & the inner payload may be several stages of shellcode to execute. Here, there would be no .exe or .dll

* often more difficult to trace/unpack

**NOTE:** The output of unpacking isn't always a .exe or .dll, it can be shellcode loaded into memory. It can also be difficult to determine when something is unpacked.


Scenario 1: Well Known Packer:

* The original exe or dll is packed

* The payload is now packed into new exe

* The original entry point now points to a new location, the unpacking process's job is to extract the payload & call that original execution point

* *PEiD* or *PE Studio* can be used to detect signatures which can tell us the packer used


Scenario 2: Unknown Packer:

* When we run PEiD or PE Studio to detect signatures, we get no results

* Manual analysis is needed to determine how it's packed & how to unpack it


Scenario 3: Modular Unpacker:

* Malicious functionality is distributed via shellcode, not via a .exe or .dll

* The shellcode is ran through a packer which returns a packed .exe

* The .exe now has to extract the functionality in the blobs of shellcode & execute it when needed

* More difficult & time consuming to trace


# Module 3

**Primary Signs of Packing:**

**NOTE:** One sign usually isn't enough to conclude a program is packed.

* Strings - Absence of strings can indicate if a program is packed while the presence of strings can indicate a program is unpacked.

* Imports - Imports allow us to understand how a program intends to interact w/the OS. Since unpacking programs need limited functionality (only to unpack the inner payload), they don't import many libraries or use many functions. So, the fewer the imports, the stronger the indication a program is packed.

* Sections - The number of sections & their names are often clues. Some packers will rename sections that give away what the file was packed with.

* Entropy - High entropy in the sections is also a leading indicator. Entropy calculates the randomness in content & ranges from 0 to 8.0. Obfuscated, compressed or encrypted code will be higher in randomness. Entropy can be applied to individual sections or the entire executable file in general.
Signature - PE file analysis tools may be able to detect common packers.

* Disassembly - If the number of identified functions and the functionality is limited, that can be an indicator the program is packed and you're looking at the unpacking logic

* Call graph from start (xrefs from start) is limited

* NOTE: A behavioral sign of unpacking is the program runs & starts a new copy of itself in a different location. The two files can be confirmed to be the same by comparing their hashes.


**PE File Format:**

* contains the structure for the binary code that will be executed by the OS when the file is ran

* broken down into 2 primary sections: *Headers* & *sections*

* Headers contain info about the file needed to load the file into memory & begin execution (IMAGE_DOS_HEADER, IMAGE_NT_HEADER, IMAGE_FILE_HEADER, HEADER, IMAGE_DATA_DIRECTORY, IMAGE_SECTION_HEADER)

* Sections contain executable code, hardcoded strings & global vars, import data & export data, & additional resources.



**Intro To PEStudio:**

* Indicators tab shows indicators that the file is malicious or packed

* PEStudio takes hash of the file & searches VirusTotal, any info is shown in the VirusTotal tab

* There are also raw PE file info such as info about the headers & sections of the file

* Dedicated tab for imports & exports

* Shows resources, strings, debug info, version info


**How Signatures Work:**
 
![example signature](https://notabug.org/s4ve/Detecting-Defeating-Packing/src/master/raw.png)

* The pattern is a series of bytes

* XX represents a wildcard, so any byte value

* This pattern is either restricted to the entry point (ep_only) or searched for in the entire binary. Searching the entire binary opens us up to more false positives

* Not all packers will leave ASCII strings w/their name behind


# Module 4

**If signatures fail...**

* Go back to the signs of packing


**Entropy:**

* Measure of randomness in code/data on a scale from 0.0-8.0

* can be used on network traffic as well as PE files

* A series of all As would have zero entropy. Compressed/encrypted content comes closer to 8.

* Entropy calculation is commonly implemented through Shannon's formula

* Entropy can be measured in the overall binary file and on the individual sections of the binary

* ~7.0 and above are strong(er) indication of packing

* ~5.0 - ~6.9 is considered normal range


**Sections:**

* Primary content of the program

* Given changable ASCII names. Changing the name has no real effect on the program.

* Common section names: .text or code, .rdata, .bss, .reloc


**Imports:**

* Programs need to import their functionality to interact w/the OS

* Commonly done by these methods: Dynamically linked (most common), runtime linking, statically linking

* Can't see the imports of a packed program

* Even small programs, when compiled, will generally have a large list of imports



**Unpacking w/Dynamic Analysis:**

* Dynamic analysis can quicken unpacking, but may still require some manual intervention
* Sandboxes & other unpacking utilities may also greatly speed up the process of unpacking



[**Packer Attacker - BromiumLabs:**](https://github.com/BromiumLabs/PackerAttacker) 

* Built off of the Detours library from Microsoft

* Supports packers that: run from the heap, replace PE headers, inject into a process


**Cuckoo's Sandbox:**

* Open source sandbox

* Supports wide range of file types

* Generates detailed report after analysis

* If desired, analysis can process system's memory for run-time artifacts. This can include obtaining unpacked executables & DLLs

* This can be complicated if malware performs anti-analysis such as detecting if it's being ran in a sandbox



# Module 5


**Unpacking by Memory Analysis:**

* Due to this method using dynamic analysis, ensure you're in a safe lab environmenet

* Look for evidence of unpacked malware in memory

* NOTE: This technique doesn't always work

* Searching for the DOS Stub "This program cannot be run in DOS mode" can assist in searching for the unpacked PE file in memory, though since the DOS stub isn't used by the OS, it can be tampered with or removed.

* Also note that if the program you're analyzing is also in the PE file format so any other libraries it's imported will be loaded into the virtual address space, so you'll find other PE files in memory but they won't be the unpacked malware you want. 

* During the unpacking process, malware will allocate additional memory for additional unpacking routines as well as a place to put the unpacked file. So we can use a debugger and set software breakpoints on memory allocations (**EX**: VirtualAlloc or VirtualAllocEx). Then you can monitor the allocations to help determine what they're used for, memory inspection cmds can help with this.

* After setting the breakpoints, we can watch the return value in the EAX/RAX register which is the address of the newly allocated memory

* When searching memory for evidence of a new PE file,, it helps if you avoid high-address regions in memory since this is usually where imported libraries are loaded


**Investigating Interesting Allocations:**

* Dump mmeory you're interested in investigating & analyze it. Simply save the bytes contained within that region of memory & use something like PEStudio or a disassembler to confirm it's the unpacked malware (retrace back to the previous steps in Module 3 and confirm it isn't packed) (dd -value- to inspect dwords in memory in windbg. d series cmds allows inspection of memory in windbg)

* db -value- gives more of a hex editor view of the value in a register in windbg (dump bytes)

* !vprot -value- outputs info regarding the allocation & the permissions, allocations w/read, write, and execute are interesting to us.


![Example !vprot](https://notabug.org/s4ve/Detecting-Defeating-Packing/src/master/exvprot.png)


* vprot will give you the base allocation base address, you can use this value and go into a tool like ProcessHacker and then save the code that is at the allocation base address. In process hacker, the sample you're analyzing is likely to be a child to the windbg.exe process

* This technique requires trial & error & may not always be successful in helping unpack malware

* You may dump corrupt PE files, so beware of this


**When Memory Analysis Fails:**

* Use a disassembler to perform more detailed analysis to understand the unpacking logic

* You'll likely want to use both static & dynamic analysis, the goal being to find key areas of functionality but let the malware do most of the work


Some key characteristics to look for when performing static analysis are:

* Unpacking code is often "one-way", meaning it doesn't likely return to the original location when called. Instead, it will transfer control maybe through a jmp or a call but remember there's no intention for it to return to the original location. After the unpacking is done, control is transferred to the now unpacked code.

* Lack of standard epilogue. jmp instead of returning, or a push of an address onto the stack and returning to that, as well as other deviations are good indicators of the unpacking logic. NOTE: When return instruction is present, it returns to the address on top of the stack, so when you see it, search for anything being pushed on the stack  to see where exactly it's returning to. 

Example of push of an address onto the stack & returning to that address:


![example push then return](https://notabug.org/s4ve/Detecting-Defeating-Packing/src/master/push-ret.png)


* These characteristics often occur at the end of the function


**Unpacking May Utilize Shellcode**

* continue tracing if using dynamic analysis 

* dump from memory & disassemble to perform static analysis

**Don't get lost in the details, look for where the shellcode finishes**

* If back to the original binary, it may be done unpacking

* Sometimes, the shellcode will change the original unpacking code to malicious code and return to that

* Or it might just unpack a file and transfer control over to the newly unpacked file in memory


**A Modular Unpacker:**

Recall that in a modular unpacker...

* The desired functionality is delivered via shellcode

* The packer then packs the shellcode within a packed executable

* The executable's job is now to extract each desired piece of functionality & execute it



